/*
 * RTSAI - Real-Time Strategy engine for AI research
 * Copyright(C) 2006 DIMAp-UFRN, licensed under LGPL
 *
 * Message declarations
 */

#ifndef MESSAGE_H
#define MESSAGE_H

#include "Log.h"
#include "Common.h"

/*! Interface for all elements able to receive messages. Useful for groups that
 * dispatch the received message to all membres of the group. An example is a
 * broadcast message for all units of a player.
 */
class MessageReceiver
{
    public:
        MessageReceiver ( ) { }
        virtual ~MessageReceiver ( ) { }
        virtual void add_message ( Message *msg )
        {
            std::cout << "teste!!!" << std::endl;
        }
};

/*! Superclass of the elements that have mailbox.
 */
class ConcreteMessageReceiver : public MessageReceiver
{
    public:
        void add_message ( Message *msg );
        int get_messages ( Message *msg_array[] );
        int get_num_messages ( );
        void clear_messages ( );

    protected:
        MailBox mbox;  // mailbox
};

/*! This class implements an interface for messages exchanges
 */
class Message
{
    public:

        /*! Agent communicative act specification. Subset of FIPA-ACL
         *  (in http://www.fipa.org/specs/fipa00037/SC00037J.html)
         */
        enum Performative {
            NONE = 0,
            CALL_FOR_PROPOSAL,  // request to other agents the cost for
                                // performing an action
            PROPOSE,            // answer the cost for performing an action
            ACCEPT_PROPOSAL,    // proposal acceptance
            REJECT_PROPOSAL,    // proposal rejection
            INFORM,             // message giving an information
            REQUEST,            // request another agent to perform an action
            AGREE,              // agree in performing an action
            REFUSE,             // refuse to perform an action
            CANCEL,             // cancel the request to perform an action
            FAILURE             // inform that the requested action could not
                                // be performed
        };

    public:
        /// Constructor of a message initializating a new conversation
        Message (Unit*, MessageReceiver*, Performative, string);

        /// Constructor of a message answering a conversation
        Message (int, Unit*, MessageReceiver*, Performative, string);

        /// Destructor
        virtual ~Message();

        // consulting methods
        Unit*            get_sender()          { return sender; }
        MessageReceiver* get_receiver()        { return receiver; }
        int              get_conversation_id() { return conversation_id; }
        Performative     get_performative()    { return performative; }
        string           get_content()         { return content; }


    private:
        /// id of the conversation the message belongs to
        int conversation_id;
        /// who is sending the message
        Unit *sender;
        /// who will receive the message
        MessageReceiver *receiver;
        /// communicative act of the message
        Performative performative;
        /// content of the message
        string content;
        /// used for stablishing new conversations
        static int unique_id;
};

#endif // MESSAGE_H
